library(readxl)
library(tidyverse)
## ── Attaching packages ────────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.0.0 ✔ purrr 0.2.5
## ✔ tibble 1.4.2 ✔ dplyr 0.7.6
## ✔ tidyr 0.8.1 ✔ stringr 1.3.1
## ✔ readr 1.1.1 ✔ forcats 0.3.0
## ── Conflicts ───────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(sf)
## Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3
library(leaflet)
library(viridis)
## Loading required package: viridisLite
library(dplyr)
knitr::opts_chunk$set(echo = TRUE)
This reads in our data that includes the suspected gang member arrest data, police beat in which the arrest occured, the gang affliation, and the age and race of the suspect. The data goes from 1999 to March of 2018.
Then we read in the shapefile of the CPD police beats, so we can map them.
df_gang_318 <- read_excel("CPD Gang Data/CPD gang database 3-18.xlsx", sheet=1)
# I downloaded the Chicago Police Beats Shapefile from the Chicago data portal
map_filepath <- "Boundaries_Police Beats/geo_export_CPD_BEATS.shp"
cpd_beats <- st_read(map_filepath)
## Reading layer `geo_export_CPD_BEATS' from data source `/Users/PrincessO/code/CPD Gang database/Boundaries_Police Beats/geo_export_CPD_BEATS.shp' using driver `ESRI Shapefile'
## Simple feature collection with 277 features and 4 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: -87.94011 ymin: 41.64455 xmax: -87.52414 ymax: 42.02303
## epsg (SRID): 4326
## proj4string: +proj=longlat +ellps=WGS84 +no_defs
#cleaning the data -- take out any rows with NA for a police beat.
df_gangs <- filter(df_gang_318, !is.na(O_BEAT))
cpd_beats <- filter(cpd_beats, !is.na(beat_num))
This preliminary map includes a popup of the police beat.
#this is just a quick map to map the police beats
cpd_beats %>%
leaflet() %>%
addTiles() %>%
addPolygons(popup=~beat_num)
After joining the dataframes, I created a new dataframe from it with a summary of the number of arrests per police beat (num_arrests).
# it looks like df_gangs needs a padded 0 in front of some of the numbers to make them 4 digits instead of 3. So let's clean that up before we join it with cpd_beats (which is all 4 digits)
df_gangs$O_BEAT <- str_pad(df_gangs$O_BEAT, 4, pad = "0")
#inner join the two data frames. Used an inner join to drop any rows where the two police beat numbers didn't match up
cpd_beats_gangs<- inner_join(cpd_beats, df_gangs, by=c('beat_num'='O_BEAT'))
#get the number of arrests per police beat and create a new data frame (CPD_gang_map2) with just that info
CPD_gang_map2 <- cpd_beats_gangs %>%
group_by(beat_num) %>%
summarize(num_arrests=n())
Using a blue color palette, and including a popup of the police beat number and the number of arrests in that police beat.
#set the color pallette as Blues.
col_pal <- colorNumeric("Blues", domain=CPD_gang_map2$num_arrests)
#Add the pop-up text with Police Beat and Number of Arrests in that area
popup_sb <- paste0("Police Beat: ", as.character(CPD_gang_map2$beat_num), "<br>Number of arrests: ", as.character(CPD_gang_map2$num_arrests))
# yaassss the following leaflet worked!
leaflet() %>%
addProviderTiles("CartoDB.Positron") %>%
setView(-87.628598, 41.855372, zoom = 10) %>%
addPolygons(data = CPD_gang_map2,
fillColor = ~col_pal(CPD_gang_map2$num_arrests),
fillOpacity = 0.7,
weight = 0.2,
smoothFactor = 0.2,
popup = ~popup_sb) %>%
addLegend(pal = col_pal,
values = CPD_gang_map2$num_arrests,
position = "bottomright",
title = "Number of Arrests")